home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.ada,comp.lang.c++
- Path: netcom.com!wnewman
- From: wnewman@netcom.com (Bill Newman)
- Subject: some questions re. Ada/GNAT from a C++/GCC user
- Message-ID: <wnewmanDoxrCp.DKv@netcom.com>
- Followup-To: comp.lang.ada,comp.lang.c++
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
- X-Newsreader: TIN [version 1.2 PL1]
- Date: Wed, 27 Mar 1996 17:02:49 GMT
- Sender: wnewman@netcom6.netcom.com
-
- I have been skimming _Ada as a Second Language_ (second edition) and I
- have looked at the GNAT documentation. I am impressed: Ada and GNAT
- look like they should do a pretty good job of meeting their design
- criteria. However, before I start planning my next project in Ada :-)
- there are a few things I'd like to know.. (I hope against hope that
- the tone of the answers will resemble the cross-language comparisons
- in _Ada as a Second Language_ more closely than it resembles the
- recent C++/Ada flamewar.)
-
- The Ada Programming FAQ pooh-poohs STL, but I like it. (Yes, I know I
- could write my own versions of what I need, but a bunch of Ada
- programmers shouldn't need to be told that that's not the ideal
- solution.) This FAQ also says the Booch components library is coming
- -- when?
-
- Does GNAT completely implement generics as defined in the standard?
- (I ask because I have heard that no compiler, G++ otherwise, has yet
- implemented C++ templates completely, and the G++ implementation
- caused me lots of hassles before 2.7.x, and still causes some hassles
- now.)
-
- I *assume* that GNAT supports exceptions completely since they're an integral
- part of the language and I didn't see any disclaimers, but since AFAIK G++
- doesn't do them very well, I'd like to double-check: how well does
- GNAT do exceptions?
-
- I didn't notice anything about garbage collection in the GNAT docs, so
- I assume it doesn't support it. Will GNAT support GC in the
- foreseeable future?
-
- How well does GDB work with GNAT output? Is it possible to get GDB to
- interactively call arbitrary procedures/functions from GNAT-generated
- code? I have been very frustrated by the way that I can't get GDB to
- call operator<<(ostream&, const Some_Class&) interactively, which
- makes it very painful to inspect the state of a program produced by
- G++. (I do *not* appreciate having to inspect my data raw field by
- raw field for every object in a complicated graph.) Would I have the
- same problem when inspecting the state of programs produced by GNAT?
-
- Is there any way in Ada to iterate abstractly over the contents of a
- container, i.e. without writing each loop in a way which depends
- strongly on the implementation of the container? I know I
- could define a container class Foo_Basket_Type which would
- let me do something like
- for I = 1 .. Size(Foo_Basket) loop -- class implemented as array
- Sum := Sum + Bletchery(Element(Foo_Basket, I));
- end loop;
- or
- I : Foo_Basket_Iterator_Type := Head(Foo_Basket);
- ..
- while not Is_Done(I) loop -- class implemented as list
- Sum := Sum + Bletchery(dereference I);
- I := Next(I);
- end loop;
- but what I'd really like to is something like
- for each I in Foo_Basket loop -- don't much care how class is implemented
- Sum := Sum + Bletchery(dereference I);
- end loop;
- I understand that in languages like Sather, I could do this without
- macros. In G++ I can come pretty close to this with CPP macros:
- FOR_EACH(i, foo_basket)
- sum += bletchery(*i);
- In standard C++ (without the G++ `typeof' operator) I'd write something like
- FOR_EACH(i, Foo_Basket::Iterator, foo_basket)
- sum += bletchery(*i);
- I use this idiom a lot -- about once per 40 lines of code in my
- current project. I much prefer it to the alternative of making my
- code depend on the implementation of the container. Is there any way of
- doing something like this in Ada? (I imagine there is, since the
- alternatives look unnecessarily difficult to maintain.)
-
- Due in part to my problems with GDB mentioned above, my C++ programs
- tend to contain a lot of calls to macros MUTTER1, MUTTER2,
- etc. defined either as no-op (for low levels of verbosity) or as
- #define MUTTER1(x) do { cerr << mutter_prefix << x << '\n'; } while (false)
- so that I can write things like
- MUTTER1("done with sampling, w = " << w << ", table = " << table);
- concisely. It's my impression that Ada's I/O facilities make it hard
- to do trivial things like this concisely. Is this wrong? I don't really
- want to have to write
- if (Global_Verbosity >= 1) then
- Write_Mutter_Indent(Global_Mutter);
- Write(Global_Mutter, "done with sampling, W = ");
- Write(Global_Mutter, W);
- Write(Global_Mutter, ", table = ");
- Write(Global_Mutter, Table);
- Write_Line(Global_Error); -- silly typo encouraged by excess verbosity
- end if;
- for a simple statement like the one above.
-
- When I make two different instantiations of a generic package with the
- same arguments, I understand the compiler treats them formally as two
- different packages, which is OK with me. However, I'd appreciate
- knowing the compiler wouldn't actually output two redundant copies of
- the corresponding (identical?) machine code, but instead share the
- code. I saw somewhere that the compiler is given considerable freedom
- to share one instantiation between several arguments if it thinks it's
- appropriate, which is also OK with me. However, I haven't seen any
- guarantee that the compiler won't output redundant copies for
- instantiations with identical arguments. Is there such a guarantee?
-
- Can someone give me an idea what kind of compilation speed I could
- expect from GNAT on a 486DX2/66 with 20 Mb of RAM, for projects of
- 1,000-50,000 lines? (I'm interested both in the time required for
- complete recompilation and in the time required for recompilation
- after a trivial local change.)
-
- My examples of `for each' and `mutter' above share a common feature:
- I'd like to abstract away a common pattern so that I only need to type
- each argument once, and I haven't figured out how to do it in Ada. I
- don't object to the rest of the verbosity I have seen in Ada: I can
- see that it might make programs more readable, and since it's checked
- by the compiler it shouldn't make programs significantly harder to
- maintain. However, the kind of verbosity required to hand-code
- patterns like `for each' and `mutter' does not seem to make code more
- readable, and since it is not checked by the compiler I'm afraid it
- might cause maintenance problems by making it possible to add bugs by
- changing some but not all occurrences of the redundant terms. Are
- there ways (e.g. in the cases described above, or other cases that I
- haven't thought of yet) in which Ada will force me to do this kind of
- thing where C++ wouldn't? If so, is this a bad thing (as I suspect),
- or is it a positive feature in some sense that I haven't figured out,
- or is it just the price we pay for the benefit of being guaranteed
- that no one has abused macros in the program?
-
- I also have a few idle questions about the design and application of
- Ada 95, more-or-less unrelated to the question of whether I'll decide
- to use it:
-
- Why doesn't Ada 95 allow declarations to be interspersed with ordinary
- statements as C++ does? (Or does it? _Ada as a Second Language_ is a
- big book!) It seems to me that the C++ approach is a small but
- definite win. Does it interact very badly somehow with all those
- guarantees on elaboration order?
-
- Someone remarked -- in this newsgroup recently IIRC -- that macros
- were explicitly disallowed in the design goals for Ada (Ada 83?),
- since they make programs hard to understand. I don't remember the
- exact wording, but as I remember the key reason was that you would
- never know what was a macro and what wasn't without reading the entire
- program hunting for macro definitions. (I searched for `macro' in the
- Rationale without success, so I'm just going on speculation and dim
- memory here.) It seems to me that that is a funny objection: most
- macro processors these days don't require a characteristic pattern to
- introduce macro expansions, but as far as I can tell there's no reason
- that you couldn't restrict macro expansion to e.g. patterns preceded
- by the keyword `macro'. Granted, C's macro facilities are fairly
- disgusting and inconsistent with the design goals of Ada, but it seems
- to me a macro facility (or `generic syntax' facility?) more consistent
- with Ada could be useful -- perhaps something closer to Scheme's
- `hygienic macros' than to C's macro preprocessor. Some restrictions
- (e.g. only allowing macros to expand into expressions, sequences of
- statements, or sequences of declarations, and not into arbitrary textual
- strings) and perhaps importing from Lisp the idea that macros are
- transformations on patterns of language tokens and expressions, rather
- than transformations on patterns of characters) could do a pretty
- decent job of discouraging people from writing truly screwy macros
- without forbidding useful macros like `For_Each' or (to generalize
- `MUTTER') `Write_Sequence' (sending a bunch of items to the same
- stream, and using the language's overloading facility to sort out
- which version of the Write procedure to call for each). Would this
- have been a good idea, except perhaps that the language is too
- complicated already, or would this be a bad idea for some more
- fundamental reason?
-
- Finally, I found it intriguing when someone (somewhere in the endless
- C++ vs. Ada thread) described a program which used exceptions to
- convert runtime errors to `graceful degradation' so successfully that
- the program (for fire control?!) continued operating more-or-less
- correctly despite numerous bugs. It seems to me that for the kinds of
- programs that I typically work on, that this would require more than
- exceptions (perhaps divine intervention?) but I can imagine that it
- would be possible for a program which was conceptually like a bunch of
- closed-loop feedback systems, without a lot of state. Therefore, it's
- my guess that the program in question was such a program. Is that a
- sensible guess? If not, i.e. if this kind of performance would be
- possible in a program with lots of state, can someone give me a
- pointer to the theory of this kind of thing? (And are there any
- examples of such fault-tolerant programs available on the net?)
- (Examples of programs with lots of state include computer operating
- systems like UNIX (or Emacs:-), or perhaps an air-traffic control
- system which needs to base its output on data up to twenty hours old
- regarding flight departure times, radar and weather reports, etc. An
- example of a system without much state would be a translation of a
- system of analog radar-guided AA gun controllers directly into
- software.)
-
- Bill Newman
- wnewman@netcom
-